<template>
  <div class="myForm">
    <el-form class="search" ref="formRef" :model="formModel" :rules="formRules" :disabled="disabled" :show-message="true" label-suffix="：" :label-position="labelPosition">
      <el-row :gutter="21" style="flex-wrap: wrap;" type="flex" v-if="formData.length">
        <el-col :key="index" :lg="item.colLg ||colLg" :md="24" :sm="24" v-for="(item, index) in formData">
          <el-form-item :label="item.label" :label-width="item.labelWidth || labelWidth" :prop="item.key||''" v-if="item.isShow||item.isShow===undefined?true:false"  :rules="item.rules">
            <!-- 标题 -->
            <div v-if="item.type == 'subtitle'" class="subtitle">
              <div class="text">{{ item.text }}</div>
              <div class="line"></div>
              <!-- <div class="subtitleRight">
                <span>新增</span>
                <img src="@/assets/images/slhgl/icon/add.png" alt="">
              </div> -->
            </div>
            <!-- 文本 -->
            <div v-if="item.type == 'text'" style="color: #fff;">{{ formModel[item.key] }}</div>
            <!-- 输入框 -->
            <el-input v-model="formModel[item.key]"
              :placeholder="'请输入' + (item.placeholder ? item.placeholder : item.label)" clearable
              v-if="item.type == 'input'"
              @change="(e)=>item.change && item.change(e,formData,formModel)"
              :disabled="item.disabled"
            >
              <template v-if="item.slotPrefixIcon">
                <i slot="prefix" :class="[item.slotPrefixIcon]"></i>
              </template>
              <template  v-else-if="item.slotPrefixText">
                <span slot="prefix">{{ item.slotPrefixText }}</span>
              </template>
              <template v-if="item.slotSuffixIcon">
                <i slot="suffix" :class="item.slotSuffixIcon"></i>
              </template>
              <template v-else-if="item.slotSuffixText">
                <span slot="suffix">{{ item.slotSuffixText }}</span>
              </template>
            </el-input>

            <!-- 输入框数字类型 -->
            <el-input v-model.number="formModel[item.key]" :maxlength="16"
              :placeholder="'请输入' + (item.placeholder ? item.placeholder : item.label)" clearable
              v-if="item.type == 'inputNumber'">
              <template v-if="item.slotPrefixIcon">
                <i slot="prefix" :class="[item.slotPrefixIcon]"></i>
              </template>
              <template  v-else-if="item.slotPrefixText">
                <span slot="prefix">{{ item.slotPrefixText }}</span>
              </template>
              <template v-if="item.slotSuffixIcon">
                <i slot="suffix" :class="item.slotSuffixIcon"></i>
              </template>
              <template v-else-if="item.slotSuffixText">
                <span slot="suffix">{{ item.slotSuffixText }}</span>
              </template>

            </el-input>

                <!-- 文本域 -->
            <el-input v-model="formModel[item.key]" type="textarea" :rows="item.rows||5" :maxlength="item.maxlength||500" show-word-limit
              :placeholder="'请输入' + (item.placeholder ? item.placeholder : item.label)" clearable
              v-if="item.type == 'textarea'" :disabled="item.disabled"
            ></el-input>

            <!-- 下拉框 -->
            <el-select v-model="formModel[item.key]" :placeholder="item.placeholder?item.placeholder:'请选择' + item.label" :disabled="item.disabled" clearable style="width:100%"
              v-if="item.type == 'select'" @change="(e)=>item.change && item.change(e,formData,formModel)"
              :filterable="item.filterable" :remote="item.remote" :remote-method="(e)=>item.remoteMethod && item.remoteMethod(e,formData,formModel)"
            >
              <el-option v-for="(ele, idx) in item.data" :key="idx"
                :label="(item.optionLabel ? ele[item.optionLabel] : ele.dictLabel)"
                :value="item.optionValue ? ele[item.optionValue] : ele.dictValue">
              </el-option>
            </el-select>

            <!-- 单选 -->
            <el-radio-group v-model="formModel[item.key]" :placeholder="'请选择' + item.label" :disabled="item.disabled" style="width:100%"
              @change="(e)=>item.change && item.change(e,formData,formModel)"
              v-if="item.type == 'radio'">
              <el-radio v-for="(ele, idx) in item.data" :key="idx"
                :label="(item.optionValue ? ele[item.optionValue] : ele.dictValue)"
                >{{(item.optionValue ? ele[item.optionValue] : ele.dictLabel)  }}</el-radio>
            </el-radio-group>
            
            <!-- 多选 -->
            <el-checkbox-group v-model="formModel[item.key]" :placeholder="'请选择' + item.label" :disabled="item.disabled" style="width:100%"
              @change="(e)=>item.change && item.change(e,formData,formModel)"
              v-if="item.type == 'checkbox'">
              <el-checkbox v-for="(ele, idx) in item.data" :key="idx"
                @click.native="item.click && item.click(ele,formData,formModel)"
                :label="(item.optionValue ? ele[item.optionValue] : ele.dictValue)"
                >{{(item.optionLabel ? ele[item.optionLabel] : ele.dictLabel)  }}</el-checkbox>
            </el-checkbox-group>
            <!-- 级联选择器 -->
            <el-cascader
              v-if="item.type == 'cascader' && item.data"
              v-model="formModel[item.key]"
              :placeholder="'请选择' + item.label" :disabled="item.disabled" clearable style="width:100%"
              :options="item.data ||[]"
              :props="item.props"
              :ref="item.key"
              :key="item.key"
              :show-all-levels="item.showAllLevels||item.showAllLevels===undefined?true:false"
              @change="(e)=>item.change && item.change(e,formData,formModel,$refs[item.key])"
            ></el-cascader>

            <!-- 上传 -->
            <el-upload
              v-if="item.type == 'upload'"
              action
              class="fileUploader"
              :show-file-list="false"
              :http-request="({ file }) => fileUpload(file,item)" :accept="item.accept||fileAccept"
              :before-upload="(file)=>beforeUpload(file,item)">
                <div class="uploadContent">
                  <div class="fileImgBox" v-for="(fileItem,fileIndex) in fileList" :key="fileIndex">
                    <!-- 模型 -->
                    <myModelView v-if="item.showType=='model'" :src='imageUrlprefix + fileItem'></myModelView>
                    <!-- 图片 -->
                    <img v-else :src="imageUrlprefix + fileItem" class="fileImg" />
                    <div class="fileImgMask" @click.self.stop="">
                      <p class="view" v-if="item.showType=='model'" @click.stop="modelViewClick(imageUrlprefix + fileItem)">
                        <i class="el-icon-zoom-in"></i>
                        预览
                      </p>
                      <p class="view" v-else @click.stop="$previewImg(imageUrlprefix + fileItem)">
                        <i class="el-icon-zoom-in"></i>
                        预览
                      </p>
                      <p class="del" @click.stop="delImg(fileIndex)">
                        <i class="el-icon-delete"></i>
                        删除
                      </p>
                    </div>
                  </div>

                  <div class="uploadeBtn" v-if="item.limit>fileList.length">
                    <i :class="isFileUploadLoading?'el-icon-loading':'el-icon-plus'"></i>
                    <span>{{isFileUploadLoading?'上传中...':'上传文件'}}</span>
                  </div>
                </div>
            </el-upload>
            <!-- 日期范围选择器 -->
            <el-date-picker
              v-if="item.type == 'daterange'"
              type="daterange"
              v-model="formModel[item.key]"
              end-placeholder="结束日期" :range-separator="item.rangeSeparator||'至'" start-placeholder="开始日期"
              style="width: 100%;"
              :value-format="item.format || 'yyyy-MM-dd'"
              >
            </el-date-picker>

            <!-- 日期时间范围选择器 -->
            <el-date-picker
              v-if="item.type == 'datetimerange'"
              type="datetimerange"
              v-model="formModel[item.key]"
              end-placeholder="结束日期" range-separator="至" start-placeholder="开始日期"
              style="width: 100%;"
              :value-format="item.format || 'yyyy-MM-dd HH:mm:ss'"
              >
            </el-date-picker>

            <!-- 日期和时间点选择器 -->
            <el-date-picker
              v-if="item.type == 'datetime'"
              type="datetime"
              v-model="formModel[item.key]"
              :placeholder="item.placeholder?item.placeholder:'选择日期时间'"
              style="width: 100%;"
              :value-format="item.format || 'yyyy-MM-dd HH:mm:ss'"
            ></el-date-picker>

            <!-- 选择日 -->
            <el-date-picker
              v-if="item.type == 'date'" type="date"
              v-model="formModel[item.key]"
              placeholder="选择日期"
              style="width: 100%;"
              :disabled="item.disabled"
              :value-format="item.format || 'yyyy-MM-dd'"
              >
            </el-date-picker>


            <!-- 年选择器 -->
            <el-date-picker
              v-if="item.type == 'year'"
              type="year"
              v-model="formModel[item.key]"
              placeholder="选择年"
              style="width: 100%;"
              :value-format="item.format || 'yyyy'"
              >
            </el-date-picker>

            <!-- 月选择器 -->
            <el-date-picker
              v-if="item.type == 'month'"
              type="month"
              v-model="formModel[item.key]"
              placeholder="选择月"
              style="width: 100%;"
              :value-format="item.format || 'yyyy-MM'"
              >
            </el-date-picker>

            <!--   插槽   -->
            <slot v-if="item.type === 'slot'" :item="item" :name="item.key" :formModel="formModel" :formData="formData"></slot>

          </el-form-item>

        </el-col>
      </el-row>
    </el-form>
  </div>
</template>

<script>
import { uploadFile } from "@/api/upload/upload";
export default {
  components:{

  },
  props: {
    labelWidth: {
      type: String,
      default: '100px',
    },
    disabled:{
      type:Boolean,
      default:false,
    },
    labelPosition: {
      type: String,
      default: 'right',
    },
    colLg: {
      type: [String, Number],
      default: 24
    },
    formData: {
      type: Array,
      default: () => []
    },
    // formModel: {
    //   type: Object,
    //   default: () => { }
    // },
    formRules: {
      type: Object,
      default: () => {}
    },
    //请求接口
    queryFn: {
      type: Function,
      // required: true,
    },
  },
  data() {
    return {
      formModel:{},
      isFileUploadLoading:false,
      fileList: [],
      fileAccept:'.jpg,.jpeg,.png',
      isShowModel:false,//模型预览
      modelSrc:'',//模型地址
    }
  },
  created() {
    this.initFormModel();// 初始化 formModel
  },
  watch:{
    formData:{
      handler(){
        this.initFormModel();// 初始化 formModel
      },
      deep:true,
    }
  },
  methods: {
    // 初始化 formModel
    initFormModel(){
      // this.formModel = this.$options.data.call(this).formModel;
      this.formData.forEach(item=>{
        if(item.type == 'inputNumber' && item.keyValue){
          item.keyValue = +item.keyValue;
        }
        if(item.type == 'upload' && item.keyValue){
          this.fileList = item.keyValue||[];
        }
        this.$set(this.formModel,[item.key],item.keyValue??'');
      })
    },
    // 提交数据
    handleSubmit() {
      this.$refs.formRef.validate(valid=>{
        if (valid) {
          // 添加提交的字段
          this.$emit('recombinationFormData', this.formModel, (newParam) => {
            if (newParam !== undefined) this.formModel = newParam
          })
          if (this.queryFn) {
            this.queryFn(this.formModel).then(res => {
              if (res && res.code == 200 && res.data) {
                this.$emit('successChange',res.data,this.formModel)
              }
            }).catch(err => {
              console.log('请求出错', err)
            })
          }else{
            this.$emit('successChange',this.formModel)
          }
        } else {
          this.$message.warning('请检查填写信息！')
          setTimeout(() => {
            document.getElementsByClassName('is-error')[0].scrollIntoView({
              behavior: 'smooth',
              block: 'center'
            })
          }, 0)
        }
      })
    },
    // 重置form表单数据和校验
    resetForm() {
      this.$refs.formRef.resetFields();
    },

    // 上传文件校验
    beforeUpload(file,item) {
      let fileAccept,fileExtension,isAcceptFile;
      item.fileMaxSize = item.fileMaxSize || 15;
      fileAccept = item.accept || this.fileAccept;
      if(typeof fileAccept == 'string'){
        fileAccept = fileAccept.split(',');
        fileExtension = file.name.substring(file.name.lastIndexOf('.'));
      }
      if(Array.isArray(fileAccept)){
        isAcceptFile = fileAccept.includes(fileExtension);
      }
      const isTrueSize = file.size / 1024 / 1024 < item.fileMaxSize;
      if (!isAcceptFile) {
        this.$message.error(`上传只能是 ${item.accept}格式!`);
      }
      if (!isTrueSize) {
        this.$message.error(`上传大小不能超过 ${item.fileMaxSize}MB!`);
      }
      return isAcceptFile && isTrueSize;
    },
    fileUpload(file, item) {
      this.isFileUploadLoading = true;
      this.uploadFile(file, item).then(res => {
        if (res && res.code == 200 && res.data) {
          this.fileList.push(res.data.url);
          this.isFileUploadLoading = false;
          this.formData.forEach(formItem=>{
            this.$set(formItem, 'keyValue', this.formModel[formItem.key]);
            if(item.key == formItem.key){
              this.$set(formItem,'keyValue',this.fileList)
            }
          })
        }
      }).catch(err => {
        this.isFileUploadLoading = false;
      })
    },
    uploadFile(file, item) {
      const formData = new FormData();
      formData.append("file", file);
      formData.append("type", item.key);
      return uploadFile(formData).then((res) => {
        return res;
      });
    },
    delImg(index) {
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.fileList.splice(index, 1);
          this.$message.success('删除成功!');
        }).catch(() => {
          this.$message.info('已取消删除!');
        });
    },
    // 模型预览
    modelViewClick(src){
      this.isShowModel=true,
      this.modelSrc=src;
    },

  },
}
</script>

<style lang="scss" scoped>
 .subtitle{
    display: flex;
    align-items: center;
    color: #0c7bf2;
    font-weight: bold;
    font-size: 14px;
    .text{
      line-height: 15px;
      padding-left: 8px;
      margin-right: 24px;
      border-left: 2px solid #0C7BF2;
    }
    .line{
      flex: 1;
      height: 1px;
      background: #d1d5dc;
    }
    .subtitleRight{
      cursor: pointer;
      margin-left: 16px;
      display: flex;
      align-items: center;
      >span{
        margin-right: 2px;
      }
      >img{
        width: 24px;
        height: 24px;
      }
    }
  }

  .fileUploader {
    width: 100%;
    display: flex;
    .uploadContent{
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-gap: 14px;
      .fileImgBox{
        position: relative;
        line-height: 0;
        width:140px;
        height:105px;
        .fileImg{
          width:140px;
          height:105px;
          border-radius: 2px;
          // margin-left: 14px;
          // margin-bottom: 14px;
        }
        .fileImgMask{
          position: absolute;
          width:140px;
          height:105px;
          top: 0;
          left: 0;
          background: rgba(0, 0, 0, 0.5);
          display: none;
        }
        &:hover .fileImgMask{
          display: flex;
          width:140px;
          height:105px;

          display: flex;
          justify-content: center;
          align-items: center;
          cursor: pointer;
          img{
            width: 24px;
            height: 24px;
          }
          p{
            display: flex;
            justify-content: center;
            align-items: center;
            i{
              font-size: 14px;
              margin-right: 2px;
            }
          }
          .view{
            color: white;
          }
          .del{
            margin-left: 12px;
            color: rgba(252, 29, 90, 1);
          }
          font-weight: 500;
          font-size: 12px;
        }
      }
      .uploadeBtn {
        width: 140px;
        height: 105px;
        border-radius: 2px;
        border: 1px solid #185678;
        background: #f3f6fd;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        >img{
          width: 24px;
          height: 24px;
        }
        i{
          font-size: 24px;
          color: #185678;
        }
        >span{
          color: #2a3347;
          font-weight: 500;
          font-size: 12px;
          line-height: 20px;
        }
      }
    }
  }
  /deep/.el-checkbox{
    margin-right: 15px;
  }
</style>
